package com.henry.rps;

// Reference: https://stackoverflow.com/questions/19204872/rock-paper-scissors-game-java

import java.util.Scanner;
import java.util.Random;

public class RockPaperScissors {
    private Random randomSource;

    public RockPaperScissors() {
        randomSource = new Random();
    }

    public enum GameType {
        EXIT, PVC, PVP;
        public static GameType parse(String val) {
            switch (val) {
                case "0": case "q": return GameType.EXIT;
                case "1": return GameType.PVC;
                case "2": return GameType.PVP;
                default: return null;
            }
        }
    }

    public enum MoveType {
        ROCK, PAPER, SCISSORS;
        public static MoveType parseType(String valIn) {
            String val = valIn.trim();
            val = val.toUpperCase();
            switch (val) {
                case "R": case "ROCK": return ROCK;
                case "P": case "PAPER": return PAPER;
                case "S": case "SCISSOR": return SCISSORS;
                default: return null;
            }
        }
        public boolean beats(MoveType other) {
            switch (this) {
                case ROCK: return other == SCISSORS;
                case SCISSORS: return other == PAPER;
                case PAPER: return other == ROCK;
                default: return false;
            }
        }
    }

    private MoveType computerMove() {
        switch (randomSource.nextInt(3)) {
            case 0: return MoveType.ROCK;
            case 1: return MoveType.PAPER;
            case 2: return MoveType.SCISSORS;
            default: return null;
        }
    }

    private static void gameChoosingMessage() {
        System.out.println("Type [1] for PvC, [2] for PvP;");
        System.out.println("Type [0/q] to exit.");
    }

    public void game() {
        Scanner keyboard = new Scanner(System.in);

        System.out.println("Welcome to play 'Rock, Paper, Scissors'!");
        gameChoosingMessage();

        GameType gameType = GameType.parse(keyboard.next().trim());

        while (gameType == null) {
            System.out.println("Illegal input! Try again.");
            gameType = GameType.parse(keyboard.next().trim());
        }

        while (gameType != GameType.EXIT) {
            System.out.print("* Type 'Rock', 'Paper' or 'Scissors'; ");
            System.out.print("(Either word or capital letter is okay, regardless of letter's case)\n");
            if (gameType == GameType.PVC) {
                System.out.print("Computer's move: ");
                MoveType computer = null;
                while (computer == null) { computer = computerMove(); }

                System.out.println("Computer made a move.");

                MoveType player = null;
                while (player == null) {
                    System.out.print("Player's move: ");
                    player = MoveType.parseType(keyboard.next().trim());
                    if (player == null) System.out.println("Illegal input! Try again.");
                }

                if (player.beats(computer)) {
                    System.out.println(player + " beats " + computer + ". Player wins!");
                } else if (computer.beats(player)) {
                    System.out.println(computer + " beats " + player + ". Computer wins!");
                } else {
                    System.out.println("It's a tie.");
                }
            } else if (gameType == GameType.PVP) {
                MoveType player1 = null;
                while (player1 == null) {
                    System.out.print("Player1's move: ");
                    player1 = MoveType.parseType(keyboard.next().trim());
                    if (player1 == null) System.out.println("Illegal input! Try again.");
                }

                MoveType player2 = null;
                while (player2 == null) {
                    System.out.print("Player2's move: ");
                    player2 = MoveType.parseType(keyboard.next().trim());
                    if (player2 == null) System.out.println("Illegal input! Try again.");
                }

                if (player1.beats(player2)) {
                    System.out.println(player1 + " beats " + player2 + ". Player1 wins!");
                } else if (player2.beats(player1)) {
                    System.out.println(player2 + " beats " + player1 + ". Player2 wins!");
                } else {
                    System.out.println("It's a tie.");
                }
            }
            gameChoosingMessage();
            gameType = GameType.parse(keyboard.next().trim());
        }
        System.out.println("Thanks for playing the game!");
    }
}

